home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
dbmalloc
/
mchain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
6KB
|
261 lines
/*
* (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
*
* This software may be distributed freely as long as the following conditions
* are met:
* * the distribution, or any derivative thereof, may not be
* included as part of a commercial product
* * full source code is provided including this copyright
* * there is no charge for the software itself (there may be
* a minimal charge for the copying or distribution effort)
* * this copyright notice is not modified or removed from any
* source file
*/
#include <stdio.h>
#include <fcntl.h>
#include "mallocin.h"
/*
* Function: malloc_chain_check()
*
* Purpose: to verify malloc chain is intact
*
* Arguments: todo - 0 - just check and return status
* 1 - call malloc_warn if error detected
*
* Returns: 0 - malloc chain intact & no overflows
* other - problems detected in malloc chain
*
* Narrative:
*
* Notes: If todo is non-zero the malloc_warn function, when called
* may not return (i.e. it may exit)
*
*/
#ifndef lint
static
char rcs_hdr[] = "$Id: mchain.c,v 1.14 1992/08/22 16:27:13 cpcahil Exp $";
#endif
int
malloc_chain_check(todo)
int todo;
{
return( DBmalloc_chain_check( (char *)NULL, 0, todo) );
}
int
DBmalloc_chain_check(file,line,todo)
CONST char * file;
int line;
int todo;
{
return( DBFmalloc_chain_check("malloc_chain_check",file,line,todo) );
}
int
DBFmalloc_chain_check(func,file,line,todo)
CONST char * func;
CONST char * file;
int line;
int todo;
{
register struct mlist * oldptr;
register struct mlist * ptr;
int rtn = 0;
MALLOC_INIT();
/*
* first check the full malloc chain
*/
oldptr = &malloc_start;
for(ptr = malloc_start.next; ; oldptr = ptr, ptr = ptr->next)
{
/*
* Since the malloc chain is a forward only chain, any
* pointer that we get should always be positioned in
* memory following the previous pointer. If this is not
* so, we must have a corrupted chain.
*/
if( ptr )
{
if(ptr < oldptr )
{
malloc_errno = M_CODE_CHAIN_BROKE;
if( todo )
{
malloc_fatal(func,file,line,oldptr);
}
rtn++;
break;
}
}
else
{
if( malloc_end && (oldptr != malloc_end) )
{
/*
* This should never happen. If it does, then
* we got a real problem.
*/
malloc_errno = M_CODE_NO_END;
if( todo )
{
malloc_fatal(func,file,line,oldptr);
}
rtn++;
}
break;
}
/*
* verify that ptr is within the malloc region...
* since we started within the malloc chain this should never
* happen.
*/
if( ((DATATYPE *)ptr < malloc_data_start)
|| ((DATATYPE *)ptr > malloc_data_end)
|| ((((long)ptr) & malloc_round) != 0) )
{
malloc_errno = M_CODE_BAD_PTR;
if( todo )
{
malloc_fatal(func,file,line,oldptr);
}
rtn++;
break;
}
/*
* verify magic flag is set
*/
if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
{
malloc_errno = M_CODE_BAD_MAGIC;
if( todo )
{
malloc_warning(func,file,line,
(struct mlist *)NULL);
}
rtn++;
continue;
}
/*
* verify segments are correctly linked together
*/
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
(ptr->next && (ptr->next->prev != ptr) ) ||
((ptr->next == NULL) && (ptr->prev == NULL)) )
{
malloc_errno = M_CODE_BAD_CONNECT;
if( todo )
{
malloc_warning(func,file,line,ptr);
}
rtn++;
continue;
}
/*
* check for under and/or overflow on this segment
*/
rtn += FILLCHECK(func,file,line,ptr,todo);
} /* for(... */
/*
* and now check the free list
*/
oldptr = NULL;
for(ptr=malloc_freelist; (rtn == 0) && (ptr != NULL); ptr=ptr->freenext)
{
/*
* Since the malloc chain is a forward only chain, any
* pointer that we get should always be positioned in
* memory following the previous pointer. If this is not
* so, we must have a corrupted chain.
*/
if( (oldptr != NULL) && (ptr < oldptr) )
{
malloc_errno = M_CODE_CHAIN_BROKE;
if( todo )
{
malloc_fatal(func,file,line,oldptr);
}
rtn++;
}
/*
* verify that ptr is within the malloc region...
* since we started within the malloc chain this should never
* happen.
*/
else if( ((DATATYPE *)ptr < malloc_data_start)
|| ((DATATYPE *)ptr > malloc_data_end)
|| ((((long)ptr) & malloc_round) != 0) )
{
malloc_errno = M_CODE_BAD_PTR;
if( todo )
{
malloc_fatal(func,file,line,oldptr);
}
rtn++;
}
/*
* verify magic flag is set
*/
else if( (ptr->flag&M_MAGIC_BITS) != M_MAGIC )
{
malloc_errno = M_CODE_BAD_MAGIC;
if( todo )
{
malloc_warning(func,file,line,
(struct mlist *)NULL);
}
rtn++;
}
/*
* verify segments are correctly linked together
*/
else if( (ptr->freeprev && (ptr->freeprev->freenext != ptr) )
|| (ptr->freenext && (ptr->freenext->freeprev != ptr) ))
{
malloc_errno = M_CODE_BAD_CONNECT;
if( todo )
{
malloc_warning(func,file,line,ptr);
}
rtn++;
}
/*
* else if this segment is in use
*/
else if( (ptr->flag & M_INUSE) != 0 )
{
malloc_errno = M_CODE_FREELIST_BAD;
if( todo )
{
malloc_warning(func,file, line,ptr);
}
rtn++;
}
/*
* else we have to check the filled areas.
*/
else
{
/*
* check for underflow and/or reuse of this segment
*/
rtn += FILLCHECK(func,file,line,ptr,todo);
}
} /* for(... */
return(rtn);
} /* malloc_chain_check(... */